package com.suncky.frame.utils;

import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.util.Base64;
import android.view.View;

import androidx.annotation.RequiresApi;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 图片工具类
 */
public class ImageUtils {

    /**
     * 压缩图片尺寸(宽高等比例压缩)
     * @param srcPath 原图片路径
     * @param toHeight 目标高度
     * @param toWidth 目标宽度
     * @return
     */
    public static Bitmap compressBitmapSize(String srcPath, int toHeight, int toWidth) {
        if (srcPath == null) {
            return null;
        }
        try {
            return compressBitmapSize(BitmapFactory.decodeFile(srcPath), toHeight, toWidth);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 压缩图片尺寸(宽高等比例压缩)
     * @param srcBitmap 原图片
     * @param toHeight 目标高度
     * @param toWidth 目标宽度
     * @return
     */
    public static Bitmap compressBitmapSize(Bitmap srcBitmap, int toHeight, int toWidth) {
        if (srcBitmap == null) {
            return null;
        }
        try {
            if ((toWidth >= srcBitmap.getWidth() && toHeight >= srcBitmap.getHeight()) || toWidth <= 0 || toHeight <= 0) {
                return srcBitmap;
            }
            final float heightRatio = (float) toHeight / (float) srcBitmap.getHeight();
            final float widthRatio = (float) toWidth / (float) srcBitmap.getWidth();
            float scale = Math.min(heightRatio, widthRatio);
            Matrix matrix = new Matrix();
            matrix.setScale(scale, scale);
            return Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 把一个路径下的图片压缩到另一个路径，忽略异常
     * @param fromPath 原图片路径
     * @param toPath 目标图片路径
     * @param maxKb 压缩后的最大体积,不大于0时不压缩体积
     * @param toHeight 压缩后的高度,不大于0时不压缩尺寸
     * @param toWidth 压缩后的宽度,不大于0时不压缩尺寸
     * @return 是否成功
     */
    public static boolean compressBitmap(String fromPath, String toPath, int maxKb, int toHeight, int toWidth) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        try {
            if (toHeight > 0 && toWidth > 0) {
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeFile(fromPath, options);
                options.inSampleSize = calculateInSampleSize(options.outWidth, options.outHeight, toWidth, toHeight);
                options.inJustDecodeBounds = false;
            }
            int degree = getAngle(fromPath);
            Bitmap srcBitmap = BitmapFactory.decodeFile(fromPath, options);
            if (degree != 0) {
                srcBitmap = getRotateBitmap(srcBitmap, degree);
            }
            if (srcBitmap == null) {
                return false;
            }
            String toDir = FileUtil.getFileDir(toPath);
            if (toDir == null || toDir.length() == 0) {
                return false;
            }
            File toDirFile = new File(toDir);
            if (!toDirFile.exists() && !toDirFile.mkdirs()) {
                return false;
            }
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int quality = 100;
            srcBitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
            if (maxKb > 0) {
                while (baos.toByteArray().length / 1024 > maxKb) {
                    // 清空baos
                    baos.reset();
                    quality -= 10;
                    if (quality <0) {
                        break;
                    }
                    srcBitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
                }
            }
            File toFile = new File(toPath);
            FileOutputStream out = new FileOutputStream(toFile);
            out.write(baos.toByteArray());
            out.flush();
            out.close();
            srcBitmap.recycle();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 图片压缩
     * @param srcBitmap 原图片
     * @param maxKb 压缩后的最大体积,不大于0时不压缩体积
     * @param toHeight 压缩后的高度,不大于0时不压缩尺寸
     * @param toWidth 压缩后的宽度,不大于0时不压缩尺寸
     * @return 压缩后的图片
     */
    public static Bitmap compressBitmap(Bitmap srcBitmap, int maxKb, int toHeight, int toWidth) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Bitmap tempBitmap = srcBitmap;
        try{
            if (toHeight > 0 && toWidth > 0) {
                srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeByteArray(baos.toByteArray(), 0, baos.size(), options);
                options.inSampleSize = calculateInSampleSize(options.outWidth, options.outHeight, toWidth, toHeight);
                options.inJustDecodeBounds = false;
                tempBitmap = BitmapFactory.decodeByteArray(baos.toByteArray(), 0, baos.size(), options);
            }
            if (maxKb > 0) {
                baos.reset();
                int quality = 100;
                tempBitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
                while (baos.toByteArray().length / 1024 > maxKb) {
                    //清空baos
                    baos.reset();
                    quality -= 10;
                    if (quality < 0) {
                        break;
                    }
                    tempBitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
                }
                return BitmapFactory.decodeByteArray(baos.toByteArray(), 0, baos.size());
            }
        }catch (Exception e){
            return null;
        }
        return tempBitmap;
    }

    /** 计算图片的缩放值
     *
     * @param srcWidth 原图片宽度
     * @param srcHeight 原图片高度
     * @param reqWidth 目标宽度
     * @param reqHeight 目标高度
     * @return
     */
    public  static int calculateInSampleSize(int srcWidth, int srcHeight, int reqWidth, int reqHeight) {
        int inSampleSize = 1;
        if (srcHeight > reqHeight || srcWidth > reqWidth) {
            final int heightRatio = Math.round((float) srcHeight / (float) reqHeight);
            final int widthRatio = Math.round((float) srcWidth / (float) reqWidth);
            inSampleSize = Math.min(heightRatio, widthRatio);
        }
        return inSampleSize;
    }

    /**
     * 读取照片exif信息中的旋转角度
     * @param path 照片路径
     * @return角度
     */
    public static int getAngle(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 读取照片exif信息中的旋转角度
     * @param is 照片InputStream
     * @return角度
     */
    @RequiresApi(api = Build.VERSION_CODES.N)
    public static int getAngle(InputStream is) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(is);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 旋转Bitmap
     * @param b
     * @param rotateDegree
     * @return
     */
    public static Bitmap getRotateBitmap(Bitmap b, float rotateDegree){
        if (rotateDegree == 0) {
            return b;
        }
        Matrix matrix = new Matrix();
        matrix.postRotate(rotateDegree);
        Bitmap rotaBitmap = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, false);
        if (b != rotaBitmap) {
            b.recycle();
        }
        return rotaBitmap;
    }

    /**
     * 旋转path下的图片
     * @param path
     * @param rotateDegree
     * @return
     */
    public static Bitmap getRotateBitmap(String path, float rotateDegree){
        Bitmap srcBitmap = BitmapFactory.decodeFile(path);
        if (rotateDegree == 0) {
            return srcBitmap;
        }
        if (srcBitmap == null) {
            return null;
        }
        Matrix matrix = new Matrix();
        matrix.postRotate(rotateDegree);
        Bitmap rotaBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, false);
        srcBitmap.recycle();
        return rotaBitmap;
    }

    /**
     * 获取图片的MIMEType
     * @param imagePath 图片路径
     * @return
     */
    public static String getMIMEType(String imagePath) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imagePath, options);
        return options.outMimeType;
    }

    /**
     * 获取图片的MIMEType
     *
     * @param uri 图片uri
     * @return
     */
    public static String getMIMEType(Context context, Uri uri) {
        if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
            return getMIMEType(uri.getPath());
        }
        try {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri), null, options);
            return options.outMimeType;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 保存bitmap到本地
     * @param bitmap 位图
     * @param path 保存路径
     * @param format 保存格式
     * @return
     */
    public static boolean saveBitmapToPath(Bitmap bitmap, String path, Bitmap.CompressFormat format) {
        if (bitmap == null || path == null) {
            return false;
        }
        File file = FileUtil.createFile(path);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            return bitmap.compress(format, 100, fos);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * bitmap转化为base64字符串
     *
     * @param bitmap 原图片
     * @param format 压缩的图片格式
     * @param quality 图片压缩质量 0-100
     * @return
     */
    public static String bitmapToBase64(Bitmap bitmap, Bitmap.CompressFormat format, int quality) {
        try{
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(format, quality, baos);
            return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
        }catch (Exception e){
            return null;
        }
    }

    /**
     * base64转为bitmap
     * @param base64Data
     * @return
     */
    public static Bitmap base64ToBitmap(String base64Data) {
        try {
            byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
            if (bytes == null || bytes.length == 0) {
                return null;
            }
            return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        }catch (Exception e){
            return null;
        }
    }

    /**
     * bitmap转化为base64字符串
     *
     * @param srcBitmap 原图片Bitmap对象
     * @param format    原图片要转化成的格式
     * @return
     */
    public static String getBase64Str(Bitmap srcBitmap, Bitmap.CompressFormat format) {
        if (srcBitmap == null) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        srcBitmap.compress(format, 100, baos);
        return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
    }

    /**
     * 将view上的内容生成图片
     * @param view View对象
     * @return
     */
    public static Bitmap getBitmapFromView(View view){
        if (view == null) {
            return null;
        }
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bitmap);
        c.drawColor(Color.TRANSPARENT);
        view.draw(c);
        return bitmap;
    }
}
